use crate::{error::SqlxErr, store::get_pool};
use serde::Serialize;
use sqlx::Row;

#[derive(Debug, Serialize)]
pub struct IpInfo {
    pub id: i64,
    pub name: String,
    pub instance_name: String,
}

pub async fn query_ip(mcu_id: i64) -> Result<Vec<IpInfo>, SqlxErr> {
    let rows = sqlx::query(r#"
        SELECT id, name, instance_name WHERE mcu_id = ?
    "#)
    .bind(mcu_id)
    .fetch_all(get_pool())
    .await?;

    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let info = IpInfo {
            id: row.get(0),
            name: row.get(1),
            instance_name: row.get(2),
        };
        vec.push(info);
    }
    Ok(vec)
}

#[derive(Debug, Serialize)]
pub struct SignalInfo {
    pub id: i64,
    pub name: String,
    pub io_modes: Option<String>,
}

pub async fn query_signals(pin_id: i64) -> Result<Vec<SignalInfo>, SqlxErr> {

    let rows = sqlx::query(r#"
        SELECT id, name, io_modes WHERE pin_id = ?
    "#)
    .bind(pin_id)
    .fetch_all( get_pool() )
    .await?;
    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let info = SignalInfo {
            id: row.get(0),
            name: row.get(1),
            io_modes: row.get(2)
        };
        vec.push(info);
    }
    Ok(vec)
}

#[derive(Debug, Serialize)]
pub struct PinInfo {
    pub id: i64,
    pub name: String,
    pub position: String,
    pub type_name: String,
}

pub async fn query_pin(mcu_id: i64) -> Result<Vec<PinInfo>, SqlxErr> {
    let rows = sqlx::query(r#"
        SELECT id, name, position, type_name FROM tb_pin WHERE mcu_id = ?
    "#)
    .bind(mcu_id)
    .fetch_all( get_pool() )
    .await?;

    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let info = PinInfo {
            id: row.get(0),
            name: row.get(1),
            position: row.get(2),
            type_name: row.get(3),
        };
        vec.push(info);
    }
    Ok(vec)
}

#[derive(Debug, Serialize)]
pub struct McuInfo {
    pub id: i64,
    pub name: String,
    pub family: String,
    pub line: String,
    pub package: String,
}

pub async fn query_mcu(line: &str) -> Result<Vec<McuInfo>, SqlxErr> {

    let rows = sqlx::query(r#"
        SELECT id, name, family, line, package FROM tb_mcu WHERE line = ?
    "#)
    .bind(line)
    .fetch_all( get_pool() )
    .await?;

    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let info = McuInfo {
            id: row.get(0),
            name: row.get(1),
            family: row.get(2),
            line: row.get(3),
            package: row.get(4)
        };
        vec.push(info);
    }

    Ok(vec)
}

pub async fn query_family() -> Result<Vec<String>, SqlxErr> {

    let rows = sqlx::query(r#"
        SELECT family FROM tb_mcu GROUP BY family
    "#)
    .fetch_all( get_pool() )
    .await?;
    
    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let family = row.get(0);
        vec.push(family);
    }
    Ok(vec)
}

pub async fn query_line(family: &str) -> Result<Vec<String>, SqlxErr> {

    let rows = sqlx::query(r#"
        SELECT line FROM tb_mcu WHERE family = ? GROUP BY line
    "#)
    .bind(family)
    .fetch_all( get_pool() )
    .await?;
    let mut vec = Vec::with_capacity(rows.len());
    for row in rows {
        let line: String = row.get(0);
        vec.push(line);
    }

    Ok(vec)
}

